import React, { useEffect, useState, Key } from 'react'
import { Card, Button, Form, Input, Table, Space, Tooltip, message } from 'antd'
import { SearchOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'
import type { ColumnsType } from 'antd/lib/table'

// 引入路由相关代码
import { useNavigate } from 'react-router-dom'

// 引入发送请求的方法
import {
  reqHospitalSets,
  reqDelOneHospitalSet,
  reqBatchDelHospitalSets,
} from '@api/hospital/hospitalSet'

//引入ts类型
import {
  IhospitalSetList,
  IhospitalResItem,
  IhospitalSetResponse,
} from '@api/hospital/model/hospitalSetTypes'

let isSearch: boolean = false // 查询表格数据时,是否添加筛选条件,为true则添加,为false则不添加
let selectKeys: Key[] = []
export default function HospitalSet() {
  const navigate = useNavigate() //实现编程式导航的函数
  const [form] = Form.useForm() // Form.useForm是antd中Form的hook,用于返回一个form实例
  // useState使用时,传入的泛型是定义hospitalSets的数据类型
  const [hospitalSets, setHospitalSets] = useState<IhospitalSetList>([])
  // 定义医院设置数据总数的状态,用于分页组件
  const [total, setTotal] = useState(50)
  //组件挂载成功,要发送请求获取医院设置的数据
  // 用于存储当前分页页码的状态
  const [page, setPage] = useState(1)

  // 用于控制表格是否展示loading效果的状态
  const [loading, setLoading] = useState(false)

  // 用于存储当前分页一页多少条的状态
  const [pageSize, setPageSize] = useState(2)

  // 定义一个控制批量删除按钮是否禁用的状态
  const [isDisabled, setIsDisabled] = useState(true)

  useEffect(() => {
    // 组件挂载完成则获取医院设置护具
    getHospitalSets(page, pageSize)
  }, [])

  // 获取表格中医院设置数据的函数
  // 执行时机: 1. 组件挂载 2. 切换分页
  async function getHospitalSets(page: number, pageSize: number) {
    setPage(page)
    setPageSize(pageSize)
    // 让loading展示
    setLoading(true)

    let result: IhospitalSetResponse
    if (isSearch) {
      // 发送请求之前,要获取到hosname和hoscode
      const { hosname, hoscode } = form.getFieldsValue()
      result = await reqHospitalSets(page, pageSize, hosname, hoscode)
    } else {
      result = await reqHospitalSets(page, pageSize)
    }

    setLoading(false)
    // 让loading隐藏
    // console.log(result)
    setHospitalSets(result.records)
    setTotal(result.total)
  }

  // 查询按钮的事件处理函数
  const onFinish = (values: any) => {
    // console.log('Success:', values)
    isSearch = true // 要将筛选条件加到请求参数中
    getHospitalSets(1, pageSize)
  }

  // 清空按钮的事件处理函数
  const clearSearchHandle = () => {
    isSearch = false
    // 清空表单
    form.setFieldsValue({ hosname: undefined, hoscode: undefined })
    // 发送请求
    getHospitalSets(1, pageSize)
  }

  // 删除一条医院数据的方法
  const deleteOneHospitalSetHandle = (id: number) => {
    return async () => {
      // 发送请求删除数据
      await reqDelOneHospitalSet(id)
      // 如果代码可以执行到这里,说明删除成功了

      // 提示用户,删除成功
      message.success('删除成功')
      // 重新获取最新的数据
      getHospitalSets(page, pageSize)
    }
  }

  // 点击跳转到添加医院设置的界面
  const goAddHospitalSet = () => {
    //修改路径,跳到添加医院设置界面
    navigate('/syt/hospital/hospitalSet/add')
  }

  // 点击跳转到修改医院设置的界面
  const goUpdateHospitalSet = (id: number) => {
    return () => {
      navigate('/syt/hospital/hospitalSet/update/' + id)
    }
  }

  // 批量按钮的事件处理函数
  const batchDelHospitalSets = async () => {
    await reqBatchDelHospitalSets(selectKeys)
    message.success('批量删除成功')
    getHospitalSets(page, pageSize)
  }

  // 这里传入IhospitalResItem,是描述table中data数据对象的类型
  const columns: ColumnsType<IhospitalResItem> = [
    {
      title: '序号', // 表示这一列的表头渲染什么

      // dataIndex: 'name', // 表示这一列渲染data数据中每一个数据对象的指定属性的值
      // 既写了dataIndex，又写了render。 最终render函数的返回值是什么，这一列就渲染什么。 但是dataIndex还是会影响到render函数接收的数据
      // 如果dataIndex不写，只写了render。则render中第一个参数接收到的就是data中的每一个数据对象
      // 如果dataIndex写了，假设的值就是name。则render中第一个参数接收到的就是data中每一个对象的name的值
      // key: 'name',
      render: (text, record, index) => {
        // console.log(text) // 是data中每一个对象的name的值
        // console.log(record) // 是data中的数据对象
        // console.log(index) // 是data中数据对象的下标

        return index + 1
      },

      align: 'center', //让这一列的数据,水平居中
      width: 80,
    },
    {
      title: '医院名称',
      dataIndex: 'hosname',
      // key: 'age',
    },
    {
      title: '医院编号',
      dataIndex: 'hoscode',
      // key: 'address',
    },
    {
      title: 'api路径',
      // key: 'tags',
      dataIndex: 'apiUrl',
    },
    {
      title: '签名',
      dataIndex: 'signKey',
      // key: 'address',
    },
    {
      title: '联系人姓名',
      dataIndex: 'contactsName',
      // key: 'address',
    },
    {
      title: '联系人手机',
      dataIndex: 'contactsPhone',
      // key: 'address',
    },
    {
      title: '操作',
      // key: 'action',
      render: (data) => (
        <Space size="middle">
          <Tooltip title="修改医院">
            <Button
              icon={<EditOutlined />}
              type="primary"
              onClick={goUpdateHospitalSet(data.id)}
            ></Button>
          </Tooltip>
          <Tooltip title="删除医院">
            <Button
              icon={<DeleteOutlined />}
              type="primary"
              danger
              onClick={deleteOneHospitalSetHandle(data.id)}
            ></Button>
          </Tooltip>
        </Space>
      ),
      fixed: 'right', // 让操作这一列,固定到表格的右侧
      width: 120, //控制这一列的宽度是120px
    },
  ]

  return (
    <Card>
      <Form
        form={form} // 使用form实例和Form表单进行绑定,后期就可以通过form实例直接操作这个Form表单
        name="basic"
        // antd中栅格系统一行24份
        // labelCol={{ span: 8 }} // 表单项的文本占一行的8份
        // wrapperCol={{ span: 16 }} // 表单项占一行的16份
        // initialValues={{ remember: true }}
        onFinish={onFinish} // 点击提交按钮,表单校验通过时触发
        // onFinishFailed={onFinishFailed} // 点击提交按钮,表单校验不通过时触发
        // autoComplete="off"
        layout="inline" // 让表单中的表单项横向排列
        style={{ marginBottom: 20 }}
      >
        <Form.Item
          // label="Username" 表单项对应的文本
          name="hosname"
          // rules就是当前表单项的表单校验规则
          // rules={[{ required: true, message: 'Please input your username!' }]}
        >
          <Input placeholder="医院名称" />
        </Form.Item>

        <Form.Item
          // label="Password"
          name="hoscode"
          // rules={[{ required: true, message: 'Please input your password!' }]}
        >
          <Input placeholder="医院编码" />
        </Form.Item>

        <Form.Item>
          {/* button上有htmlType="submit" 表示当前按钮是当前表单的提交按钮 */}
          <Button icon={<SearchOutlined />} type="primary" htmlType="submit">
            查询
          </Button>
        </Form.Item>
        <Form.Item>
          <Button onClick={clearSearchHandle}>清空</Button>
        </Form.Item>
      </Form>

      <Button
        type="primary"
        style={{ marginRight: 10 }}
        onClick={goAddHospitalSet}
      >
        添加
      </Button>
      <Button
        type="primary"
        danger
        disabled={isDisabled}
        onClick={batchDelHospitalSets}
      >
        批量删除
      </Button>
      {/* columns: 控制表单当中的表头显示什么内容 , dataSource: 决定了表格的具体渲染的数据*/}
      <Table
        loading={loading}
        columns={columns}
        dataSource={hospitalSets}
        style={{ marginTop: 20 }}
        bordered //为表格添加边框
        rowKey={'id'} // 让table渲染的时候,使用每一条数据中的id
        scroll={{ x: 1500 }} // 表格水平方向展示滚动条. 1500表示限制表格的宽度,超过这个宽度就会有滚动条
        pagination={{
          current: page, // 控制分页中哪个页码高亮
          pageSize, // 控制分页中一页展示多少条数据
          // pagination用于控制表格中的分页
          total, // 用于控制分页中的数据总数,默认一页是10条

          showTotal: function (total) {
            return `总共: ${total}`
          }, // 在分页的最前面,展示数据总数
          showSizeChanger: true, // 展示可以修改一页多少条数据的控件
          pageSizeOptions: ['2', '5', '10'], // 自定义修改一页多少条数据的下拉框
          // onChange在点击页码,或修改一页多少条的时候触发(只要操作了分页的组件,onchange就会触发)
          // onChange: function (page, pageSize) {
          //   // page:  就是刚刚点击的页码
          //   // pageSize: 就是刚刚选择的一页多少条
          //   setPage(page)
          //   setPageSize(pageSize)
          // },
          onChange: getHospitalSets,
          showQuickJumper: true, // 展示快速跳转到第几页的控件
        }}
        // table中展示复选框
        rowSelection={{
          // 只要修改了复选框,onChange就会触发
          // Key 是react包中提供的一个ts的数据类型, 表示唯一值
          onChange: (selectedRowKeys: Key[]) => {
            // console.log(selectedRowKeys)
            // 如果selectedRowKeys有id,则说明用户选中了,选中要取消禁用,如果selectedRowKeys没有id,则说明用户什么都没选,就要禁用
            setIsDisabled(!selectedRowKeys.length)
            // 动态修改全局变量
            selectKeys = selectedRowKeys
          },
        }}
      />
    </Card>
  )
}
